home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Precision Software Appli…tions Silver Collection 4
/
Precision Software Applications Silver Collection Volume 4 (1993).iso
/
stats
/
chadyn.exe
/
YLORENZ.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-11-28
|
7KB
|
272 lines
/********************************* YLorenz.C *********************************/
/*********************** (C) 1986,7,8 by JAMES A. YORKE **********************/
#include "yinclud.h"
/*********** Lorenz 1 mode --- 3 equations ***********/
DELorenz(k, Y)
double Y[],
k[];
{
int i,
base;
double x1,
y1val, /* Y1 is a global variable */
z1;
double J00,
J01,
J10,
J11,
J12,
J20,
J21,
J22;
x1 = Y[0];
y1val = Y[1];
z1 = Y[2];
k[0] = -sigma * (x1 - y1val);
k[1] = rho * x1 - y1val - x1 * z1;
k[2] = x1 * y1val - beta * z1;
k[3] = 1; /* time */
if(num_lyap > 0) {
J00 = -sigma;
J01 = sigma;
J10 = rho - z1;
J11 = -1.;
J12 = -x1;
J20 = y1val;
J21 = x1;
J22 = -beta;
}
for(i = 0; i < num_lyap; i++) {
base = lyapzero + vec_dim * i;
k[base + 0] =
J00 * Y[base] + J01 * Y[base + 1];
k[base + 1] =
J10 * Y[base] + J11 * Y[base + 1] + J12 * Y[base + 2];
k[base + 2] =
J20 * Y[base] + J21 * Y[base + 1] + J22 * Y[base + 2];
}
}
initLorenz() {
/* Lorenz */
int DELorenz();
vec_dim = 3; /* the dimension of the Lyapunov vectors =
phase space dim */
num_lyap = 0; /* the number of Lyapunov numbers to be
computed <= vec_dim */
lyapzero = 4; /* y[lyapzero] is the zeroth coord of the
zeroth lyapunov vector */
dim = lyapzero + num_lyap * vec_dim;
/* needed for rungekutta */
X_upper = 25.0; /* x scale */
X_lower = -25.;
Y_upper = 60.; /* y scale */
Y_lower = 0.;
Y_coord = 2;
sigma = 10;
rho = 28.0;
beta = 8./ 3.;
step = 1./ 100.;
DE = DELorenz; /* DE is a pointer to a function */
}
DESam(k, Y)
double Y[],
k[];
{
int i,
base;
double x1,
y1val, /* Y1 is a global variable */
z1;
double J00,
J01,
J02,
J10,
J11,
J12,
J20,
J21,
J22;
x1 = Y[0];
y1val = Y[1];
z1 = Y[2];
k[0] = C1 * x1 + C2 * y1val - z1;
k[1] = C3 * x1 + C5 * y1val - C6 * x1 * x1 * x1;
k[2] = rho * x1;
k[3] = 1; /* time */
if(num_lyap > 0) {
J00 = C1;
J01 = C2;
J02 = -1;
J10 = C3 - 3 * C6 * x1 * x1;
J11 = C5;
J12 = 0;
J20 = rho;
J21 = 0;
J22 = 0;
}
for(i = 0; i < num_lyap; i++) {
base = lyapzero + vec_dim * i;
k[base + 0] =
J00 * Y[base] + J01 * Y[base + 1] + J02 * Y[base + 2];
k[base + 1] =
J10 * Y[base] + J11 * Y[base + 1] + J12 * Y[base + 2];
k[base + 2] =
J20 * Y[base] + J21 * Y[base + 1] + J22 * Y[base + 2];
}
}
initSam() {
#ifdef IGNORE
TESTMAP2 ("sam")
fputs(
"SAM Samardzia system: x'= C1*x+C2*y-z, y'= C3*x+C5*y-C6*x^3, z'= rho*x\n"
,output);
TESTMAP("sam")
fputs(
"Numbering of variables: y[0]=x ,y[1]=y, y[2]=z, y[3]=time \n"
,output);
#endif
/* Nick Samardzia - DuPont 302-695-3009 */
int DESam();
num_lyap = 0; /* the number of Lyapunov numbers to be
computed <= vec_dim */
vec_dim = 3; /* the dimension of the Lyapunov vectors =
phase space dim */
lyapzero = 4; /* y[lyapzero] is the zeroth coord of the
zeroth lyapunov vector */
X_upper = 2.0; /* x scale */
X_lower = -2.;
Y_lower = -2.; /* y scale */
Y_upper = 2.;
X_coord = 0;
Y_coord = 1;
C1 =.032;
C2 =.5;
C3 = 1.;
C5 = -.1;
C6 = 1.;
rho = 0.1;
step =.04;
rho_step =.02;
DE = DESam; /* DE is a pointer to a function */
}
ReturnMap() { /* this routine will iterate (*DEsolver) until
Fn() changes sign from positive to negative,
that is, until old_Fn>0 and new_Fn<=0); the
time between crossings(= "time" at the end
of this routine) is returned; for
differential equations it is necessary to
check to see if some variable(possibly
time) should be taken mod something; Fn()
must be chosen so that the mod operation
does not decrease Fn from positive to
negative; if the cross section is going to
be set up so that time t = some t0, and t is
increasing and is taken mod 1, say, then
define Fn() = t0 - t so that the mod
increases Fn; intermediate data on finding
cross section is printed out when "printer"
== 3 */
double time,
savestep,
old_Fn,
new_Fn,
old_y[EQUATIONS];
new_Fn = (*Fn) ();
old_Fn = new_Fn; /* since new_fn = old_fn, the "for()" will be
traversed at least once */
for(time = 0; (level >= PROCESS) && ((old_Fn <= 0) || (new_Fn > 0));
time = time + step) {
/* continue cycling unless Fn() decreases from
> 0 to <= 0 */
old_Fn = new_Fn;
store(old_y, y, dim);
(*DEsolver) ();
(*modPointer) ();
/* this = null() for non differential equations
and for many differential equations */
/* if this mod causes(*Fn)() to decrease past 0, we have a problem */
new_Fn = (*Fn) ();
if(printer == 3) {
scr_rowcol(2, 0);
printf(
"quick: Hit 2 to stop all this printing; then hit c to clear the screen \n");
Interrupt();
printf(
"(*Fn)() = %12.10lf time = %12.10lf, step = %12.10lf \n"
,new_Fn, time, step);
}
}
savestep = step;
while(level >= PROCESS && fabs (new_Fn) >.00000001) {
/* fabs() is absolute value of a double
precision number */
step = step * old_Fn / (old_Fn - new_Fn);
/* estimated time step needed to hit(*Fn)() =
0 starting from old_y */
sixth_step = step / 6;/* for rungekutta() */
halfstep = step / 2;
store(y, old_y, dim);
(*DEsolver) ();
(*modPointer) ();
/* this = null() for non differential equations
and for many differential equations */
/* if this modulo causes(*Fn)() to decrease past 0, we have a problem
*/
new_Fn = (*Fn) ();
if(printer == 3) {
scr_rowcol(2, 0);
printf(
"REFINING CROSSING POINT: new Fn = %12.10lf; new step = %12.10lf \n"
,new_Fn, step);
Interrupt();
}
}
time = time - savestep + step;
/* trajectory overshot in first part so what
was then step must be subtracted off and we
add the partial step which at this moment is
called step */
step = savestep;
sixth_step = step / 6; /* for rungekutta() */
halfstep = step / 2;
if(printer == 3)
printf("time for loop: %12.10lf \n", time);
return;
}
initLRetMap() {
extern double Fn3 ();
extern int ReturnMap();
Fn = Fn3; /* for poincare return map */
iteratee = ReturnMap;
initLorenz();
Y_coord = 1; /* X_coord = 0 */
Y_upper = 10.; /* x & y scales are symmetric */
Y_lower = -10.;
X_upper = 10.0; /* x scale */
X_lower = -10.;
}